#region License and Copyright

/*
 * Copyright (C) 2008 Nathan Palmer
 * http://www.nathanpalmer.com
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Author:
 *     Nathan Palmer <nathan1@nathanpalmer.com>
 */

#endregion

using System;
using System.Collections.Generic;
using System.Text;
using Amazon.S3.com.amazonaws.s3;
using System.IO;
using Microsoft.Win32;

namespace Amazon.S3
{
    public class S3Keys : IEnumerable<S3Key>
    {
        private List<S3Key> keys;
        private S3Helper helper;
        private S3Bucket parent;
        private string prefix;

        internal S3Keys(S3Helper Helper, S3Bucket Parent)
        {
            helper = Helper;
            parent = Parent;
        }

        internal S3Keys(S3Helper Helper, S3Bucket Parent, string Prefix)
            : this(Helper, Parent)
        {
            prefix = Prefix;
        }

        private void LoadKeys()
        {
            keys = new List<S3Key>();

            SoapResponse<ListBucketResult> soapResponse;
            if (helper.ListBucket(parent.Name, prefix, null, null, 100, out soapResponse))
            {
                if (soapResponse.State.Contents != null)
                {
                    ListEntry[] entries = soapResponse.State.Contents;
                    foreach (ListEntry entry in entries)
                    {
                        keys.Add(new S3Key(entry, parent, helper));
                    }
                }
            }
        }

        public S3Key this[string Name]
        {
            get
            {
                if (keys == null)
                    LoadKeys();

                foreach (S3Key key in keys)
                {
                    if (key.Name == Name)
                    {
                        return key;
                    }
                }

                return null;
            }
        }

        public S3Key this[int Index]
        {
            get
            {
                if (keys == null)
                    LoadKeys();

                return keys[Index];
            }
        }

        public int Count
        {
            get
            {
                return keys.Count;
            }
        }

        public S3Key Add(string FilePath, string FileName)
        {
            FileInfo file = new FileInfo(Path.Combine(FilePath, FileName));
            SoapResponse<PutObjectResult> soapResponse;

            if (helper.PutObject(parent.Name, FileName, helper.GetContentType(file.Extension), file.Length, file.OpenRead(), null, null, out soapResponse))
            {
                LoadKeys();

                return this[FileName];
            }
            else
            {
                return null;
            }
        }

        public S3Key Add(string FileName, byte[] FileData)
        {
            MemoryStream ms = new MemoryStream(FileData);
            SoapResponse<PutObjectResult> soapResponse;

            string[] fileNameParts = FileName.Split(new char[] { '.' });
            string fileExtension = "S3Object";
            if (fileNameParts.Length > 1)
            {
                fileExtension = "." + fileNameParts[fileNameParts.Length - 1];
            }

            if (helper.PutObject(parent.Name, FileName, helper.GetContentType(fileExtension), ms.Length, ms, null, null, out soapResponse))
            {
                LoadKeys();

                return this[FileName];
            }
            else
            {
                return null;
            }
        }

        public bool Delete(string Name)
        {
            S3Key key = this[Name];
            if (key != null)
            {
                SoapResponse<Status> soapResponse;
                if (helper.DeleteObject(parent.Name, Name, out soapResponse))
                {
                    keys.Remove(key);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        #region IEnumerable<S3Key> Members

        public IEnumerator<S3Key> GetEnumerator()
        {
            if (keys == null)
                LoadKeys();

            return keys.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
